# vnc.py
import tkinter as tk
from tkinter import ttk, messagebox
import threading

try:
    # 尝试导入VNC库
    from vncdotool import api

    VNC_AVAILABLE = True
except ImportError:
    VNC_AVAILABLE = False


class VNCViewer:
    def __init__(self, root):
        self.root = root
        self.root.title("VNC Viewer")
        self.root.geometry("1024x768")

        # VNC连接参数（默认值）
        self.vnc_host = "10.15.4.10"
        self.vnc_port = 5900
        self.vnc_password = "jk,1234"

        # 初始化状态
        self.connected = False
        self.vnc_client = None
        self.vnc_thread = None
        self.stop_flag = False

        self.create_widgets()

    def create_widgets(self):
        """创建界面组件"""
        # 创建工具栏
        toolbar = ttk.Frame(self.root)
        toolbar.pack(side=tk.TOP, fill=tk.X, padx=5, pady=5)

        self.connect_btn = ttk.Button(toolbar, text="连接", command=self.connect_vnc)
        self.connect_btn.pack(side=tk.LEFT, padx=2)

        self.disconnect_btn = ttk.Button(toolbar, text="断开", command=self.disconnect_vnc, state=tk.DISABLED)
        self.disconnect_btn.pack(side=tk.LEFT, padx=2)

        self.settings_btn = ttk.Button(toolbar, text="设置", command=self.show_settings)
        self.settings_btn.pack(side=tk.LEFT, padx=2)

        self.fullscreen_btn = ttk.Button(toolbar, text="全屏", command=self.toggle_fullscreen)
        self.fullscreen_btn.pack(side=tk.LEFT, padx=2)

        # 连接信息显示
        info_frame = ttk.LabelFrame(toolbar, text="连接信息")
        info_frame.pack(side=tk.RIGHT, padx=10)

        self.info_label = ttk.Label(info_frame, text=f"主机: {self.vnc_host}:{self.vnc_port}")
        self.info_label.pack(side=tk.LEFT)

        # 创建VNC显示区域
        self.main_frame = ttk.Frame(self.root)
        self.main_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

        # 使用文本区域显示状态信息
        self.status_text = tk.Text(self.main_frame, bg="black", fg="white", font=("Courier", 12))
        self.status_text.pack(fill=tk.BOTH, expand=True)
        self.status_text.insert(tk.END, "VNC Viewer\n")
        self.status_text.insert(tk.END, "==========\n")
        self.status_text.insert(tk.END, "1. 点击'设置'配置服务器信息\n")
        self.status_text.insert(tk.END, "2. 点击'连接'开始会话\n")
        self.status_text.insert(tk.END, "3. 确保VNC服务器可访问\n\n")

        if not VNC_AVAILABLE:
            self.status_text.insert(tk.END, "警告: 未安装vncdotool库\n")
            self.status_text.insert(tk.END, "请运行: pip install vncdotool\n")

        # 状态栏
        self.status_var = tk.StringVar(value="就绪 - 点击'连接'按钮开始远程控制")
        status_bar = ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)
        status_bar.pack(side=tk.BOTTOM, fill=tk.X)

        # 设置事件绑定
        self.setup_bindings()

    def setup_bindings(self):
        """设置事件绑定"""
        # 键盘事件
        self.root.bind("<Key>", self.on_key_press)
        self.status_text.focus_set()

    def show_settings(self):
        """显示设置对话框"""
        settings_window = tk.Toplevel(self.root)
        settings_window.title("VNC设置")
        settings_window.geometry("300x200")
        settings_window.resizable(False, False)

        # 居中显示
        settings_window.transient(self.root)
        settings_window.grab_set()

        # 主机设置
        ttk.Label(settings_window, text="主机地址:").grid(row=0, column=0, sticky=tk.W, padx=10, pady=10)
        self.host_var = tk.StringVar(value=self.vnc_host)
        host_entry = ttk.Entry(settings_window, textvariable=self.host_var, width=20)
        host_entry.grid(row=0, column=1, padx=10, pady=10)

        # 端口设置
        ttk.Label(settings_window, text="端口:").grid(row=1, column=0, sticky=tk.W, padx=10, pady=10)
        self.port_var = tk.StringVar(value=str(self.vnc_port))
        port_entry = ttk.Entry(settings_window, textvariable=self.port_var, width=20)
        port_entry.grid(row=1, column=1, padx=10, pady=10)

        # 密码设置
        ttk.Label(settings_window, text="密码:").grid(row=2, column=0, sticky=tk.W, padx=10, pady=10)
        self.password_var = tk.StringVar(value=self.vnc_password)
        password_entry = ttk.Entry(settings_window, textvariable=self.password_var, width=20, show="*")
        password_entry.grid(row=2, column=1, padx=10, pady=10)

        # 按钮框架
        button_frame = ttk.Frame(settings_window)
        button_frame.grid(row=3, column=0, columnspan=2, pady=20)

        def save_settings():
            self.vnc_host = self.host_var.get()
            try:
                self.vnc_port = int(self.port_var.get())
            except ValueError:
                messagebox.showerror("错误", "端口必须是数字")
                return
            self.vnc_password = self.password_var.get()

            # 更新显示信息
            self.info_label.config(text=f"主机: {self.vnc_host}:{self.vnc_port}")
            settings_window.destroy()

        ttk.Button(button_frame, text="保存", command=save_settings).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="取消", command=settings_window.destroy).pack(side=tk.LEFT, padx=5)

    def connect_vnc(self):
        """连接到VNC服务器"""
        if not VNC_AVAILABLE:
            messagebox.showerror("错误", "缺少VNC库，请安装vncdotool:\npip install vncdotool")
            return

        self.status_var.set("正在连接到 {}:{}...".format(self.vnc_host, self.vnc_port))
        self.root.update()

        # 在后台线程中连接VNC
        self.vnc_thread = threading.Thread(target=self._connect_worker)
        self.vnc_thread.daemon = True
        self.vnc_thread.start()

    def _connect_worker(self):
        """VNC连接工作线程"""
        try:
            # 使用vncdotool连接VNC服务器
            vnc_url = f"{self.vnc_host}:{self.vnc_port}"
            self.vnc_client = api.connect(vnc_url, password=self.vnc_password)

            # 连接成功后的UI更新
            self.root.after(0, self._on_connect_success)

        except Exception as e:
            self.root.after(0, lambda: self._on_connect_error(str(e)))

    def _on_connect_success(self):
        """连接成功的回调"""
        self.connected = True
        self.status_var.set("已连接到 {}:{} | 可以开始操作".format(self.vnc_host, self.vnc_port))
        self.connect_btn.config(state=tk.DISABLED)
        self.disconnect_btn.config(state=tk.NORMAL)
        self.status_text.focus_set()

        # 更新状态显示
        self.status_text.delete(1.0, tk.END)
        self.status_text.insert(tk.END, f"已连接到 {self.vnc_host}:{self.vnc_port}\n")
        self.status_text.insert(tk.END, "可以开始远程操作\n")
        self.status_text.insert(tk.END, "鼠标和键盘事件将被转发到远程桌面\n")

    def _on_connect_error(self, error_msg):
        """连接失败的回调"""
        self.status_var.set("连接失败: {}".format(error_msg))
        messagebox.showerror("连接错误",
                             "无法连接到VNC服务器:\n{}\n\n建议:\n1. 检查网络连接\n2. 确认VNC服务器运行状态\n3. 验证IP地址和端口\n4. 检查密码是否正确".format(
                                 error_msg))

    def disconnect_vnc(self):
        """断开VNC连接"""
        try:
            if self.vnc_client:
                self.vnc_client.disconnect()

            self.connected = False
            self.vnc_client = None

            # 更新UI状态
            self.status_var.set("已断开连接")
            self.connect_btn.config(state=tk.NORMAL)
            self.disconnect_btn.config(state=tk.DISABLED)

            # 更新状态显示
            self.status_text.delete(1.0, tk.END)
            self.status_text.insert(tk.END, "连接已断开\n")
            self.status_text.insert(tk.END, "点击'连接'按钮重新连接\n")

        except Exception as e:
            messagebox.showerror("错误", "断开连接时出错: {}".format(str(e)))

    def on_key_press(self, event):
        """键盘按键事件"""
        if not self.connected or not self.vnc_client:
            return

        try:
            # 发送按键事件到远程桌面
            key = event.keysym
            self.vnc_client.keyPress(key)
            self.status_var.set("按键: {}".format(key))
        except Exception as e:
            self.status_var.set("键盘事件发送错误: {}".format(str(e)))

    def toggle_fullscreen(self):
        """切换全屏模式"""
        is_fullscreen = self.root.attributes('-fullscreen')
        self.root.attributes('-fullscreen', not is_fullscreen)

    def on_closing(self):
        """窗口关闭事件处理"""
        if self.connected:
            self.disconnect_vnc()
        self.root.destroy()


def create_vnc_interface():
    """
    创建VNC客户端图形界面
    """
    root = tk.Tk()
    app = VNCViewer(root)
    root.protocol("WM_DELETE_WINDOW", app.on_closing)
    return root


def main():
    """主函数"""
    print("VNC Viewer")
    print("==========")
    print("使用说明:")
    print("1. 安装VNC库: pip install vncdotool")
    print("2. 点击'设置'按钮配置VNC服务器信息")
    print("3. 点击'连接'按钮开始会话")
    print("4. 确保目标VNC服务器可访问")

    # 创建并运行界面
    app = create_vnc_interface()
    app.mainloop()


if __name__ == "__main__":
    main()
